package test04;

import java.util.*;


public class SimpleMusicInterpreter {

    // 1. 首先，我们定义一个"音乐表达式"的通用接口
    // 就像所有乐器都能发出声音一样，所有音乐元素都要能"播放"
    interface MusicExpression {
        void play();  // 播放这个音乐元素
    }

    // 2. 实现"音符表达式" - 代表具体的音符，比如 "C", "D", "E"
    static class NoteExpression implements MusicExpression {
        private String noteName;   // 音符名称，比如 "C", "D", "E"
        private String duration;   // 音符时长，比如 "全音符", "四分音符"

        public NoteExpression(String noteName, String duration) {
            this.noteName = noteName;
            this.duration = duration;
        }

        @Override
        public void play() {
            // 这里我们模拟播放音符
            // 在实际应用中，这里会生成对应频率的声音
            System.out.println("🎵 播放音符 " + noteName + " (" + duration + ")");

            // 简单模拟：根据音符名称播放不同的"声音"
            switch(noteName) {
                case "C": System.out.println("  发出 Do 的声音"); break;
                case "D": System.out.println("  发出 Re 的声音"); break;
                case "E": System.out.println("  发出 Mi 的声音"); break;
                case "F": System.out.println("  发出 Fa 的声音"); break;
                case "G": System.out.println("  发出 Sol 的声音"); break;
                case "A": System.out.println("  发出 La 的声音"); break;
                case "B": System.out.println("  发出 Si 的声音"); break;
            }
        }
    }

    // 3. 实现"休止符表达式" - 代表音乐中的停顿
    static class RestExpression implements MusicExpression {
        private String duration;   // 休止时长

        public RestExpression(String duration) {
            this.duration = duration;
        }

        @Override
        public void play() {
            // 休止符就是什么声音都不发，等待一段时间
            System.out.println("⏸️  休止符 (" + duration + ") - 安静等待");
        }
    }

    // 4. 音乐播放器 - 负责管理和播放所有的音乐表达式
    static class MusicPlayer {
        private List<MusicExpression> expressions = new ArrayList<>();

        // 添加音乐表达式到播放列表
        public void addExpression(MusicExpression expression) {
            expressions.add(expression);
        }

        // 播放所有的音乐表达式
        public void playAll() {
            System.out.println("🎼 开始演奏音乐...");
            for (MusicExpression expression : expressions) {
                expression.play();

                // 在音符之间添加短暂的延迟，让演示更清晰
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            System.out.println("🎉 演奏结束！");
        }
    }

    // 5. 简单的音乐解析器 - 把字符串转换成音乐表达式
    static class SimpleMusicParser {
        /**
         * 解析音乐字符串
         * 格式： "C D E R F" 
         * 其中：C,D,E,F,G,A,B 代表音符，R 代表休止符
         */
        public static List<MusicExpression> parse(String musicString) {
            List<MusicExpression> result = new ArrayList<>();
            String[] tokens = musicString.split(" ");  // 用空格分割每个音符

            for (String token : tokens) {
                if (token.equals("R")) {
                    // R 表示休止符
                    result.add(new RestExpression("四分休止符"));
                } else if (token.matches("[A-G]")) {
                    // A-G 表示音符，使用四分音符作为默认时长
                    result.add(new NoteExpression(token, "四分音符"));
                }
                // 这里可以扩展支持更多格式
            }
            return result;
        }
    }

    // 6. 主程序 - 演示如何使用
    public static void main(String[] args) {
        System.out.println("=== 简单音乐解释器演示 ===");
        System.out.println();

        // 创建一个音乐播放器
        MusicPlayer player = new MusicPlayer();

        // 示例1：解析简单的音乐字符串 "C D E F G A B"
        System.out.println("示例1: 音阶上行");
        String scale = "C D E F G A B";
        System.out.println("乐谱: " + scale);

        List<MusicExpression> scaleExpressions = SimpleMusicParser.parse(scale);
        for (MusicExpression expr : scaleExpressions) {
            player.addExpression(expr);
        }
        player.playAll();

        System.out.println("\n" + "=".repeat(30) + "\n");

        // 示例2：带休止符的旋律
        System.out.println("示例2: 带休止符的旋律");
        String melody = "C C G G A A G R F F E E D D C";
        System.out.println("乐谱: " + melody);

        // 清空之前的表达式
        player = new MusicPlayer();
        List<MusicExpression> melodyExpressions = SimpleMusicParser.parse(melody);
        for (MusicExpression expr : melodyExpressions) {
            player.addExpression(expr);
        }
        player.playAll();

        System.out.println("\n" + "=".repeat(30) + "\n");

        // 示例3：手动创建音乐表达式
        System.out.println("示例3: 手动创建音乐");
        player = new MusicPlayer();

        // 手动添加音符和休止符
        player.addExpression(new NoteExpression("C", "四分音符"));
        player.addExpression(new NoteExpression("E", "四分音符"));
        player.addExpression(new NoteExpression("G", "二分音符"));
        player.addExpression(new RestExpression("四分休止符"));
        player.addExpression(new NoteExpression("C", "全音符"));

        player.playAll();
    }
}